/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.ufg.inf.si.poo.formula1.Team;

import br.ufg.inf.si.poo.formula1.Driver.Driver;

/**
 * Team
 * 
 * Versao 1.0
 * 
 * Data 19/01/2013
 * 
 * @author Igor
 */
public class Team {
    //Atributos
    private String fullName;
    private String shortName;
    private String base;
    private String teamPrincipal;
    private String techinicalChief;
    private Driver[] drivers;
    private String chassis;
    private String engine;
    private String tyres;
    private int firstSeason;
    private int worldChampionchips;
    private int[] highestRaceFinish;
    private int polePositions;
    private int fastesLaps;
    private int points;

    //Construtores
    public Team(){
        this.fullName = "";
        this.shortName = "";
        this.base = "";
        this.teamPrincipal = "";
        this.techinicalChief = "";
        this.chassis = "";
        this.engine = "";
        this.tyres = "";
        this.firstSeason = 0;
        this.worldChampionchips = 0;
        this.highestRaceFinish = new int[2];
        this.highestRaceFinish[0] = 0;
        this.highestRaceFinish[1] = 0;
        this.polePositions = 0;
        this.fastesLaps = 0;
        this.drivers = new Driver[4];
        this.points = 0;
    }

    public Team(
            String fullName, 
            String shortName,
            String base,
            String teamPrincipal,
            String techinicalChief,
            String chassis,
            String engine,
            String tyres,
            int firstSeason,
            int worldChampionships,
            int highestRaceFinish1,
            int highestRaceFinish2,
            int polePositions,
            int fastestLaps
            ){
        /* Esse construtor recebe estes parametros pois o sao os dados que 
         o arquivo INICIAl contem */
        this.fullName = fullName;
        this.shortName = shortName;
        this.base = base;
        this.teamPrincipal = teamPrincipal;
        this.techinicalChief = techinicalChief;
        this.chassis = chassis;
        this.engine = engine;
        this.tyres = tyres;
        this.firstSeason = firstSeason;
        this.worldChampionchips = worldChampionships;
        this.highestRaceFinish = new int[2];
        this.highestRaceFinish[0] = highestRaceFinish1;
        this.highestRaceFinish[1] = highestRaceFinish2;
        this.polePositions = polePositions;
        this.fastesLaps = fastestLaps;
        this.drivers = new Driver[4];
        this.points = 0;
    }

    //Metodos Getters and Setters
    /**
     * Retorna o atributo fullName (nome completo)
     * @return o atributo fullName
     */
    public String getFullName() {
        return fullName;
    }

    /**
     * Altera o atributo fullName (nome completo)
     * @param fullName altera o atributo nome completo
     */
    public void setFullName(String fullName) {
        this.fullName = fullName;
    }

    /**
     * Retorna o atributo shortName (nome abreviado)
     * @return o atributo shortName
     */
    public String getShortName() {
        return shortName;
    }

    /**
     * Altera o atributo shortName (nome abreviado)
     * @param shortName altera o atributo nome breve
     */
    public void setShortName(String shortName) {
        this.shortName = shortName;
    }

    /**
     * Retorna o atributo base (local da sede)
     * @return o atributo base
     */
    public String getBase() {
        return base;
    }

    /**
     * Altera o atributo base (local da sede)
     * @param base retorna o atributo base
     */
    public void setBase(String base) {
        this.base = base;
    }

    /**
     * Retorna o atributo teamPrincipal (diretor)
     * @return o atributo teamPrincipal
     */
    public String getTeamPrincipal() {
        return teamPrincipal;
    }

    /**
     * Altera o atributo teamPrincipal (diretor)
     * @param teamPrincipal altera o chefe da equipe
     */
    public void setTeamPrincipal(String teamPrincipal) {
        this.teamPrincipal = teamPrincipal;
    }

    /**
     * Retorna o atributo techinicalChief (chefe tecnico)
     * @return o atributo techinicalChief
     */
    public String getTechinicalChief() {
        return techinicalChief;
    }

    /**
     * Altera o atributo techinicalChief (chefe tecnico)
     * @param techinicalChief altera o diretor técnico
     */
    public void setTechinicalChief(String techinicalChief) {
        this.techinicalChief = techinicalChief;
    }

    /**
     * Retorna o atributo drivers (vetor contendo ate 4 pilotos)
     * @return o atributo driver
     */
    public Driver[] getDriver() {
        return drivers;
    }

    /**
     * Altera o atributo drivers (vetor contendo ate 4 pilotos)
     * @param driver altera o atributo driver
     */
    public void setDriver(Driver[] driver) {
        this.drivers = driver;
    }

    /**
     * Retorna o atributo chassis
     * @return o atributo chassis
     */
    public String getChassis() {
        return chassis;
    }

    /**
     * Altera o atributo chassis
     * @param chassis altera o atributo chassis
     */
    public void setChassis(String chassis) {
        this.chassis = chassis;
    }

    /**
     * Retorna o atributo engine (empresa que fez o motor)
     * @return o atributo engine
     */
    public String getEngine() {
        return engine;
    }

    /**
     * Altera o atributo engine engine (empresa que fez o motor)
     * @param engine altera o motor da equipe
     */
    public void setEngine(String engine) {
        this.engine = engine;
    }

    /**
     * Retorna o atributo tyres (fabricante dos pneus)
     * @return o atributo tyres
     */
    public String getTyres() {
        return tyres;
    }

    /**
     * Altera o atributo tyres (fabricante dos pneus)
     * @param tyres altera os pneus da equipe
     */
    public void setTyres(String tyres) {
        this.tyres = tyres;
    }

    /**
     * Retorna o atributo firstSeason (primeira temporada que participou)
     * @return o atributo firstSeason
     */
    public int getFirstSeason() {
        return firstSeason;
    }

    /**
     * Altera o atributo firstSeason (primeira temporada que participou)
     * @param firstSeason altera o atributo firstSeason
     */
    public void setFirstSeason(int firstSeason) {
        this.firstSeason = firstSeason;
    }

    /**
     * Retorna o atributo worldChampionchips (quantas vezes foi campeao mundial de contrutores)
     * @return o atributo worldChampionships
     */
    public int getWorldChampionchips() {
        return worldChampionchips;
    }

    /**
     * Altera o atributo worldChampionchips (quantas vezes foi campeao mundial de contrutores)
     * @param worldChampionchips altera o atributo worldChampionships
     */
    public void setWorldChampionchips(int worldChampionchips) {
        this.worldChampionchips = worldChampionchips;
    }

    /**
     * Retorna o atributo highestRaceFinish (vetor com qual melhor posicao finalizou a corrida e quantas vezes se repetiu)
     * @return o atributo highestRaceFinish
     */
    public int[] getHighestRaceFinish() {
        return highestRaceFinish;
    }

    /**
     * Altera o atributo highestRaceFinish (vetor com qual melhor posicao finalizou a corrida e quantas vezes se repetiu)
     * @param highestRaceFinish altera o atributo highestRaceFinish
     */
    public void setHighestRaceFinish(int highestRaceFinish) {
        if( (highestRaceFinish < this.highestRaceFinish[0]) || (this.highestRaceFinish[0] == 0) ){
            this.highestRaceFinish[0] = highestRaceFinish;
            this.highestRaceFinish[1] = 1;
        }else if(highestRaceFinish ==  this.highestRaceFinish[0]){
            this.highestRaceFinish[1]++;
        }
    }

    /**
     * Retorna o atributo polePositions (quantas vezes largou em primeiro lugar)
     * @return o atributo polePositions
     */
    public int getPolePositions() {
        return polePositions;
    }

    /**
     * Altera o atributo polePositions (quantas vezes largou em primeiro lugar)
     * @param polePositions altera o atributo polePositions
     */
    public void setPolePositions(int polePositions) {
        this.polePositions = polePositions;
    }

    /**
     * Retorna o atributo fastesLaps (quantas vezes seus pilotos fizeram a volta mais rapida)
     * @return o atributo fastestLaps
     */
    public int getFastesLaps() {
        return fastesLaps;
    }

    /**
     * Altera o atributo fastesLaps (quantas vezes seus pilotos fizeram a volta mais rapida)
     * @param fastesLaps altera o atributo fastestLaps
     */
    public void setFastesLaps(int fastesLaps) {
        this.fastesLaps = fastesLaps;
    }

    /**
     * Retorna o atributo points (pontuacao total da equipe)
     * @return o atributo points
     */
    public int getPoints() {
        return points;
    }

    /**
     * Altera o atributo points (pontuacao total da equipe)
     * @param points altera o atributo points
     */
    public void setPoints(int points) {
        this.points = points;
    }

    //Outros Metodos
    /**
     * Reescrita do metodo toStrng
     * Preenche o retorno com os dados do relatorio da equipe
     * @return String com o relatório de dados da Equipe
     */
    @Override 
    public String toString(){
        String data = "";
        
	data += this.shortName + "\n"
		+ "________________________________________________\n"
		+ "Full Team Name:\t\t" + this.fullName + "\n"
		+ "Base:\t\t\t" + this.base + "\n"
		+ "Team Principal:\t\t" + this.teamPrincipal + "\n"
		+ "Technical Chief:\t" + this.techinicalChief + "\n"
		+ "Drivers:\n";
        for(int i = 0;i < 4;i++){
            if(this.getDriver()[i] != null){
                data += "\t\t\t" + this.getDriver()[i].getDriverName() + "\n";
            }                
        }
	data += "Chassis:\t\t" + this.chassis + "\n"
		+ "Engine:\t\t\t" + this.engine + "\n"
		+ "Tyres:\t\t\t" + this.tyres + "\n"
		+ "First Season:\t\t" + this.firstSeason + "\n"
		+ "World Championships:\t" + this.worldChampionchips + "\n"
		+ "Highest Race Finish:\t" + this.highestRaceFinish[0] +" (x"+this.highestRaceFinish[1] +")"+ "\n"
		+ "Pole Positions:\t\t" + this.polePositions + "\n"
		+ "Fastest Laps:\t\t" + this.fastesLaps + "\n";
        return data;
    }

    /**
     * Demite o piloto, desvincula-o da equipe e a equipe do piloto
     * @param driver, a equipe demite o piloto passado
     * @throws IllegalArgumentException 
     */
    public void dismissDriver(Driver driver) throws IllegalArgumentException {
        boolean demitiu = false;

        for(int i = 0;i < 4;i++){
            if(this.getDriver()[i] != null){
                if(this.getDriver()[i].getDriverName().equals(driver.getDriverName())){
                    this.getDriver()[i] = null;
                    driver.setTeam(null);
                    demitiu = true;
                }
            }
        }
        if(!demitiu){
            throw new IllegalArgumentException("Impossível desvincular piloto");
        }
    }
    
    /**
     * Contrata o piloto, vincula-o aa equipe e a equipe ao piloto
     * @param driver, a equipe contratara o piloto passado
     * @throws IllegalArgumentException 
     */
    public void hireDriver(Driver driver) throws IllegalArgumentException {
        int i = 0;
         /* Só contrata se o piloto não possuir Equipe */
        if(driver.getTeam() == null){
            while( (i < 4)&&(this.getDriver()[i] != null) ){
                i++;
            }

            if(i < 4) {
                this.getDriver()[i] = driver;
                driver.setTeam(this);
            }else{
                throw new IllegalArgumentException("Equipe já possui 4 pilotos vinculados.");
            }
        }else{
            throw new IllegalArgumentException("Piloto já está vinculado a uma equipe.");
        }
    }

    /**
     * Reescrita do metodo equals
     * Verifica se a equipe passada como parâmentro é a mesma equipe do objeto
     * @param anObject
     * @return true ou false, caso seja igual ou nao, respectivamente
     */
    @Override
    public boolean equals(Object anObject){
        if(anObject instanceof Team){
            if(this.shortName.equals(((Team) anObject).getShortName())){
                return true;
            }
        }
        return false;
    }

    /**
     * Reescrita do hashCode, devido aa reescrita do metodo equals
     * @return true ou false
     */
    @Override
    public int hashCode() {
        int hash = 3;
        hash = 53 * hash + (this.shortName != null ? this.shortName.hashCode() : 0);
        return hash;
    }

    /**
     * Define os pilotos que participaram das corridas
     * @param driver1, tornará o primeiro Piloto da lista, sendo o primeiro a ser escolhido para correr
     * @param driver2, tornará o segundo Piloto da lista, sendo o segundo a ser escolhido para correr
     * @throws IllegalArgumentException 
     */
    public void regRaceDriver(Driver driver1, Driver driver2) throws IllegalArgumentException {
	Driver aux;
	boolean flag = false;

        /*Define driver1 para posição 0 do vetor, pois os pilotos que irão correr são determinados pelas posições 0 e 1 do vetor
        */
	for(int i = 0;i < 4;i++){
            if(this.getDriver()[i] != null){
		if(this.getDriver()[i].getDriverName().equals(driver1.getDriverName())){
                    if(this.getDriver()[0] != null){
			aux = this.getDriver()[0];
			this.getDriver()[0] = this.getDriver()[i];
			this.getDriver()[i] = aux;
                    }else{
                        this.getDriver()[0] = this.getDriver()[i];
                    }
                    flag = true;
                    break;
		}
            }
	}
	if (!flag){
            throw new IllegalArgumentException("Piloto "+driver1.getDriverName()+" não faz parte da Equipe.");
	}

        /* Define driver2 para a posição 1 do vetor 
        */
        flag = false;
	for(int i = 0;i < 4;i++){
            if(this.getDriver()[i] != null){
		if(this.getDriver()[i].getDriverName().equals(driver2.getDriverName())){
                    if(this.getDriver()[1] != null){
                        aux = this.getDriver()[1];
                        this.getDriver()[1] = this.getDriver()[i];
                        this.getDriver()[i] = aux;
                    }else{
                        this.getDriver()[1] = this.getDriver()[i];
                    }
                    flag = true;
                    break;
		}
            }
	}
	if (!flag){
            throw new IllegalArgumentException("Piloto "+driver2.getDriverName()+" não faz parte da Equipe.");
	}
    }
}
